package mbean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.model.SelectItem;

import util.Constantes;
import util.FacesUtil;
import vo.BSCPerspectiveVO;
import vo.SwotElementVO;
import vo.SwotVO;
import dao.BSCPerspectiveDAO;
import dao.SwotDAO;

public class SWOTMBean extends AbstractMBean{
	
	private SwotDAO dao;
	private String name, description, headerPanelNewItem, newItemName, relevanceNewItem;
	private int linhaSelecionada, selectedItemType, strategicPlanId, id;
	private List<BSCPerspectiveVO> listAcronymPerspective;
	private List<SwotElementVO> listStrength, listWeakness, listOpportunity, listThreat;
	private List<Integer> listaStrengthRemovido, listaWeaknessRemovido, listaOpportunityRemovido, listaThreatRemovido;
	private Map<String, Map<String, List<SwotElementVO>>> mapaPerspectiva;
	private List<String> listaPerspectives, listaUsedPerspectives, perspectiveSelected;
	private Map<String, BSCPerspectiveVO> mapaPerspectives;
	private List<SelectItem> listaSIPerspectives;
	
	public SWOTMBean(){
		this.dao = new SwotDAO();
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getDescription() {
		return description;
	}

	public void setListAcronymPerspective(List<BSCPerspectiveVO> listAcronymPerspective) {
		this.listAcronymPerspective = listAcronymPerspective;
	}

	public List<BSCPerspectiveVO> getListAcronymPerspective() {
		return listAcronymPerspective;
	}

	public void setListStrength(List<SwotElementVO> listStrength) {
		this.listStrength = listStrength;
	}

	public List<SwotElementVO> getListStrength() {
		return listStrength;
	}

	public void setLinhaSelecionada(int linhaSelecionada) {
		this.linhaSelecionada = linhaSelecionada;
	}

	public int getLinhaSelecionada() {
		return linhaSelecionada;
	}

	public void setSelectedItemType(int selectedItemType) {
		this.selectedItemType = selectedItemType;
	}

	public int getSelectedItemType() {
		return selectedItemType;
	}
	
	public String open(){
		BSCPerspectiveDAO bscpDAO = new BSCPerspectiveDAO();		
		this.strategicPlanId = ((StrategyMBean) FacesUtil.getSessionMapValue("strategy")).getStrategicPlanId();
		mapaPerspectives = bscpDAO.getUsedPerspectives(this.strategicPlanId);
		
		listAcronymPerspective = new ArrayList<BSCPerspectiveVO>();
		listaPerspectives = new ArrayList<String>();
		listaUsedPerspectives = new ArrayList<String>();
		listaSIPerspectives = new ArrayList<SelectItem>();
		
		SelectItem si = new SelectItem();
		si.setLabel(FacesUtil.getMessageResourceString("all"));
		si.setValue(" ");
		this.listaSIPerspectives.add(si);
		
		for(String key: mapaPerspectives.keySet()){
			BSCPerspectiveVO vo = mapaPerspectives.get(key);
			listaPerspectives.add(key);
			listAcronymPerspective.add(vo);
			
			si = new SelectItem();
			si.setLabel(vo.getPerspective());
			si.setValue(vo.getAcronym());
			this.listaSIPerspectives.add(si);
		}
		
		loadSwot();
		this.selectedItemType = -1;
		
		montaMapaPerspectiva(mapaPerspectives);
		setPerspectiveSelected(new ArrayList<String>());
		filterPerspective();
		setaTela(true, "swot");
		
		return "swot";
	}
	
	private void montaMapaPerspectiva(Map<String, BSCPerspectiveVO> perspectivas) {
		this.mapaPerspectiva = new HashMap<String, Map<String, List<SwotElementVO>>>();
		
		for(String key: perspectivas.keySet()){
			BSCPerspectiveVO vo = perspectivas.get(key);
			Map<String, List<SwotElementVO>> temp = new HashMap<String, List<SwotElementVO>>();
			temp.put(Constantes.STRENGTH, new ArrayList<SwotElementVO>());
			temp.put(Constantes.WEAKNESS, new ArrayList<SwotElementVO>());
			temp.put(Constantes.OPPORTUNITY, new ArrayList<SwotElementVO>());
			temp.put(Constantes.THREAT, new ArrayList<SwotElementVO>());
			
			mapaPerspectiva.put(vo.getAcronym(), temp);
		}
		
		addMapaPerspectiva(this.listStrength, Constantes.STRENGTH);
		addMapaPerspectiva(this.listWeakness, Constantes.WEAKNESS);
		addMapaPerspectiva(this.listOpportunity, Constantes.OPPORTUNITY);
		addMapaPerspectiva(this.listThreat, Constantes.THREAT);
	}

	private void addMapaPerspectiva(List<SwotElementVO> elements, String elementType) {
		for(SwotElementVO vo:elements){
			for(String key:vo.getListPerspectives()){
				mapaPerspectiva.get(key).get(elementType).add(vo);				
			}
		}
	}

	public String loadSwot(){
		SwotVO swot = dao.getSwot(strategicPlanId);		
		name = swot.getNome();
		description = swot.getDescricao();
		id = swot.getId();		
		listStrength = swot.getListStrength();
		listWeakness = swot.getListWeakness();
		listOpportunity = swot.getListOpportunity();
		listThreat = swot.getListThreat();
		
		preencheRelevanciaExtenso(listStrength);
		preencheRelevanciaExtenso(listWeakness);
		preencheRelevanciaExtenso(listOpportunity);
		preencheRelevanciaExtenso(listThreat);
		
		this.listaStrengthRemovido = new ArrayList<Integer>();
		this.listaWeaknessRemovido = new ArrayList<Integer>();
		this.listaOpportunityRemovido = new ArrayList<Integer>();
		this.listaThreatRemovido = new ArrayList<Integer>();
		
		return "view-swot";
	}
	
	private void preencheRelevanciaExtenso(List<SwotElementVO> lista) {
		for (SwotElementVO vo:lista){
			if (vo.getRelevancia().equalsIgnoreCase("1"))
				vo.setRelevanciaExtenso(FacesUtil.getMessageResourceString("relevanceLow"));
			else if (vo.getRelevancia().equalsIgnoreCase("2"))
				vo.setRelevanciaExtenso(FacesUtil.getMessageResourceString("relevanceMedium"));
			else if (vo.getRelevancia().equalsIgnoreCase("3"))
				vo.setRelevanciaExtenso(FacesUtil.getMessageResourceString("relevanceHigh"));
		}
	}

	public void saveSwot(){
		this.perspectiveSelected = new ArrayList<String>();
		this.selectedItemType = -1;
		filterPerspective();
		
		SwotVO vo = new SwotVO();
		vo.setId(id);
		vo.setNome(name);
		vo.setDescricao(description);
		vo.setStrategicPlanId(this.strategicPlanId);
		vo.setListStrength(listStrength);
		vo.setListWeakness(listWeakness);
		vo.setListOpportunity(listOpportunity);
		vo.setListThreat(listThreat);
		
		dao.saveSwot(vo, listaStrengthRemovido, listaWeaknessRemovido, listaOpportunityRemovido, listaThreatRemovido);
		
		MenuMBean mmb = (MenuMBean) FacesUtil.getSessionMapValue("menu");
		mmb.loadTree();
	}

	public void filterPerspective(){
		insertMapa(this.listStrength, Constantes.STRENGTH);
		insertMapa(this.listWeakness, Constantes.WEAKNESS);
		insertMapa(this.listOpportunity, Constantes.OPPORTUNITY);
		insertMapa(this.listThreat, Constantes.THREAT);
		
		this.listStrength = new ArrayList<SwotElementVO>();
		this.listWeakness = new ArrayList<SwotElementVO>();
		this.listOpportunity = new ArrayList<SwotElementVO>();
		this.listThreat = new ArrayList<SwotElementVO>();
		
		for(String perspective:getPerspectiveSelected()){
			if (perspective.equalsIgnoreCase(" ")){
				populaLista(this.listStrength, Constantes.STRENGTH);
				populaLista(this.listWeakness, Constantes.WEAKNESS);
				populaLista(this.listOpportunity, Constantes.OPPORTUNITY);
				populaLista(this.listThreat, Constantes.THREAT);
				
				break;
			}
			else{
				this.listStrength.addAll(this.mapaPerspectiva.get(perspective).get(Constantes.STRENGTH));
				this.listWeakness.addAll(this.mapaPerspectiva.get(perspective).get(Constantes.WEAKNESS));
				this.listOpportunity.addAll(this.mapaPerspectiva.get(perspective).get(Constantes.OPPORTUNITY));
				this.listThreat.addAll(this.mapaPerspectiva.get(perspective).get(Constantes.THREAT));
			}
		}
	}
	
	private void populaLista(List<SwotElementVO> elements, String elementType) {
		for(String key:this.mapaPerspectiva.keySet()){
			for(SwotElementVO svo:this.mapaPerspectiva.get(key).get(elementType))
				if (! elements.contains(svo))
					elements.add(svo);
		}
	}

	private void insertMapa(List<SwotElementVO> elements, String elementType) {
		for(SwotElementVO vo:elements){
			if (vo.getId() == 0){
				for(String key:vo.getListPerspectives()){
					this.mapaPerspectiva.get(key).get(elementType).add(vo);
				}				
			}
		}
	}

	public void deleteItem(){
		if (this.selectedItemType == 1){
			SwotElementVO vo = this.listStrength.get(this.linhaSelecionada);
			listaStrengthRemovido.add(vo.getId());
			this.listStrength.remove(this.linhaSelecionada);
			
			for(String key:vo.getListPerspectives()){
				this.mapaPerspectiva.get(key).get(Constantes.STRENGTH).remove(vo);
			}
		}
		else if (this.selectedItemType == 2){
			SwotElementVO vo = this.listWeakness.get(this.linhaSelecionada);
			listaWeaknessRemovido.add(vo.getId());
			this.listWeakness.remove(vo);
			
			for(String key:vo.getListPerspectives()){
				this.mapaPerspectiva.get(key).get(Constantes.WEAKNESS).remove(vo);
			}
		}
		else if (this.selectedItemType == 3){
			SwotElementVO vo = this.listOpportunity.get(this.linhaSelecionada);
			listaOpportunityRemovido.add(vo.getId());
			this.listOpportunity.remove(vo);
			
			for(String key:vo.getListPerspectives()){
				this.mapaPerspectiva.get(key).get(Constantes.OPPORTUNITY).remove(vo);
			}
		}
		else if (this.selectedItemType == 4){
			SwotElementVO vo = this.listThreat.get(this.linhaSelecionada);
			listaThreatRemovido.add(vo.getId());
			this.listThreat.remove(vo);
			
			for(String key:vo.getListPerspectives()){
				this.mapaPerspectiva.get(key).get(Constantes.THREAT).remove(vo);
			}
		}
		
		saveSwot();
	}

	public void setListWeakness(List<SwotElementVO> listWeakness) {
		this.listWeakness = listWeakness;
	}

	public List<SwotElementVO> getListWeakness() {
		return listWeakness;
	}

	public void setListOpportunity(List<SwotElementVO> listOpportunity) {
		this.listOpportunity = listOpportunity;
	}

	public List<SwotElementVO> getListOpportunity() {
		return listOpportunity;
	}

	public void setListThreat(List<SwotElementVO> listThreat) {
		this.listThreat = listThreat;
	}

	public List<SwotElementVO> getListThreat() {
		return listThreat;
	}
	
	public int getListAcronymPerspectiveSize(){
		return this.listAcronymPerspective.size();
	}

	public Map<String, Map<String, List<SwotElementVO>>> getMapaPerspectiva() {
		return mapaPerspectiva;
	}
	
	public void newItem(){
		if (this.selectedItemType == 1){
			this.headerPanelNewItem = "Strength";
		}
		else if (this.selectedItemType == 2){
			this.headerPanelNewItem = "Weakness";
		}
		else if (this.selectedItemType == 3){
			this.headerPanelNewItem = "Opportunity";
		}
		else if (this.selectedItemType == 4){
			this.headerPanelNewItem = "Threat";
		}
		
		this.newItemName = "";
	}

	public void setHeaderPanelNewItem(String headerPanelNewItem) {
		this.headerPanelNewItem = headerPanelNewItem;
	}

	public String getHeaderPanelNewItem() {
		return headerPanelNewItem;
	}

	public void setNewItemName(String newItemName) {
		this.newItemName = newItemName;
	}

	public String getNewItemName() {
		return newItemName;
	}

	public void setRelevanceNewItem(String relevanceNewItem) {
		this.relevanceNewItem = relevanceNewItem;
	}

	public String getRelevanceNewItem() {
		return relevanceNewItem;
	}

	public void setListaPerspectives(List<String> listaPerspectives) {
		this.listaPerspectives = listaPerspectives;
	}

	public List<String> getListaPerspectives() {
		return listaPerspectives;
	}

	public void setListaUsedPerspectives(List<String> listaUsedPerspectives) {
		this.listaUsedPerspectives = listaUsedPerspectives;
	}

	public List<String> getListaUsedPerspectives() {
		return listaUsedPerspectives;
	}

	public void setMapaPerspectives(Map<String, BSCPerspectiveVO> mapaPerspectives) {
		this.mapaPerspectives = mapaPerspectives;
	}

	public Map<String, BSCPerspectiveVO> getMapaPerspectives() {
		return mapaPerspectives;
	}
	
	public void saveNewItem(){
		SwotElementVO vo = new SwotElementVO();
		vo.setName(this.newItemName);
		vo.setRelevancia(this.relevanceNewItem);

		String perspectives = "";
		int i = 0;
		for(String str: this.listaUsedPerspectives){
			BSCPerspectiveVO bscvo = this.mapaPerspectives.get(str);
			if (i == 0)
				perspectives = bscvo.getAcronym();
			else
				perspectives = perspectives + ", " + bscvo.getAcronym();
			
			i++;
		}
		
		vo.setPerspective(perspectives);
		
		if (this.selectedItemType == 1){
			vo.setElementType(Constantes.STRENGTH);
			this.listStrength.add(vo);
		}
		else if (this.selectedItemType == 2){
			vo.setElementType(Constantes.WEAKNESS);
			this.listWeakness.add(vo);
		}
		else if (this.selectedItemType == 3){
			vo.setElementType(Constantes.OPPORTUNITY);
			this.listOpportunity.add(vo);
		}
		else if (this.selectedItemType == 4){
			vo.setElementType(Constantes.THREAT);
			this.listThreat.add(vo);
		}		
		
		saveSwot();
	}

	@Override
	public boolean isDirty() {
		boolean dirty = false;
		
		SwotVO swot = dao.getSwot(strategicPlanId);	
		
		if (! swot.getNome().equalsIgnoreCase(this.name))
			dirty = true;
		
		if (! swot.getDescricao().equalsIgnoreCase(this.description))
			dirty = true;
		
		return dirty;
	}
	
	public String backPerspective(){
		setaTela(true, "swot");
		return "back";
	}
	
	public String openPerspectiveView(){
		setaTela(false, "");
		return "perspective";
	}

	public void setListaSIPerspectives(List<SelectItem> listaSIPerspectives) {
		this.listaSIPerspectives = listaSIPerspectives;
	}

	public List<SelectItem> getListaSIPerspectives() {
		return listaSIPerspectives;
	}

	public void setPerspectiveSelected(List<String> perspectiveSelected) {
		this.perspectiveSelected = perspectiveSelected;
	}

	public List<String> getPerspectiveSelected() {
		if (perspectiveSelected.size() == 0){
			perspectiveSelected.add(" ");
		}
		return perspectiveSelected;
	}
}